<?php
/**
 * Geneone: Content Management Framework
 * Forum Object
 *
 * http://geneone.neondragon.net/
 *
 * @package Geneone
 * @author Khlo
 * @version 1.0
 * @copyright 2004-2006 Geneone Development Team
 */

class Gene_Object_Model_Forum extends Gene_Object_Model {
	/**
	 * Extra RDF Namespaces required.
	 */
	var $rdfNamespaces = array();
	
	/**
	 * Default column ordering.
	 */
	var $orderBy = "t_create DESC";
	
	/**
	 * @static
	 * @return string Globally unique ID for this object type
	 */
	function getObjectTypeGuid() {
		return "http://geneone.neondragon.net/objects/forum/";
	}
	
	/**
	 * @static
	 * @return string Object type version
	 */
	function getObjectTypeVersion() {
		// Must be in PHP standardized version format.
		// See http://uk.php.net/version_compare
		return "1.0";
	}
	
	/**
	 * @static
	 * @return string Allowed Child Type GUIDs
	 */
	function getAllowedChilds() {
		return array("http://geneone.neondragon.net/objects/discussion/", "http://geneone.neondragon.net/objects/forum/", "http://geneone.neondragon.net/objects/redirect/");
	}
	
	/**
	 * @static
	 * @return string Allowed Parent Type GUIDs
	 */
	function getAllowedParents() {
		return array("*");
	}
	
	/**
	 * @static
	 * @return string GUIDs of other objects of which this object is compatible with.
	 */
	function getCompatibleObjectGuids() {
		return array();
	}
	
	/**
	 * Class constructor.
	 *
	 * Here we can set up the class for use. Set up any
	 * variables we might need, etc.
	 *
	 * @var array $info Object Info
	 */
	function Gene_Object_Model_Forum($info) {
		$this->info =& $info;
		$this->objectID = $info['object_id'];
	}
	
	/**
	 * Create a new forum object.
	 *
	 * DO NOT use this function directly - use Gene_Object_Model::create()
	 *
	 * @static
	 *
	 * @var string $title Object Title
	 * @var string $desc Object Description
	 * @var string $content Object Contents
	 * @var object $parentobj Instance of parent object
	 * @var array $options New Object options
	 *
	 * @return mixed Returns the object ID of the newly created object
	 *               on success or a PEAR_Error object containing a
	 *               descriptive error message on failure.
	 */
	function create($title='', $desc='', $content='', &$parentobj, $options=array()) {
		$db =& Gene::getDatabase();
		
		if (strlen($title) < 3) {
			return PEAR::raiseError("You must specify a title of at least 3 characters.");
		}
		
		$parent = $parentobj->get();
		
		// Remove new lines
		$title = str_replace (array("\n", "\r"), '', $title);
		$desc = str_replace (array("\n", "\r"), '', $desc);
		
		$newid = $db->nextId(Gene::tableName("objects"));
		
		$user =& Gene::getUser();
		
		// Parents CSV String
		if ($parent['parentcsv'] == "-1") {
			$parents = $parent['object_id'];
		} else {
			$parents = $parent['parentcsv'].",".$parent['object_id'];
		}
		
		$objtime = time();
		
		$newobject = array(
			"object_id" => $newid,
			"type" => "forum",
			"title" => $title,
			"description" => $desc,
			"content" => Gene_Object::cleanHtml($content),
			"owner_id" => $user->getUserId(),
			"parent" => $parent['object_id'],
			"parentcsv" => $parents,
			"t_create" => $objtime,
			
			// Public Forum Settings
			"p_view" => "*",
			"p_edit" => "o",
			"p_revisions" => "o",
			"p_write" => "*",
			"p_moderate" => $parent['p_moderate'],
		);
		
		$db->extended->autoExecute(
			Gene::tableName("objects"),
			$newobject,
			MDB2_AUTOQUERY_INSERT
		);
		
		// Update parent child count
		$parentobj->bumpChildNumber();
		
		/* Revisions */
		if (!isset($options['revision_summary'])) {
			$options['revision_summary'] = "";
		}
		
		if (isset($options['revision_minor'])) {
			$options['revision_minor'] = $options['revision_minor'] ? '1' : '0';
		} else {
			$options['revision_minor'] = '0';
		}
		
		// Insert revision
		$revision = array(
			"revision_id" => $db->nextId(Gene::tableName("object_revisions")),
			"object_id" => $newid,
			"title" => $title,
			"description" => $desc,
			"content" => $content,
			"rev_summary" => $options['revision_summary'],
			"rev_minor" => $options['revision_minor'],
			"rev_time" => $objtime,
			"user_id" => $user->getUserId(),
		);
		
		$db->extended->autoExecute(
			Gene::tableName("object_revisions"),
			$revision,
			MDB2_AUTOQUERY_INSERT
		);
		
		/* Discussions Table */
		$discussion = array(
			"object_id" => $newid,
			"priority" => 3,
			"readonly" => 0,
			"last_comment_id" => $newid,
			"last_comment_time" => $objtime,
			"last_comment_user" => $user->getUserId(),
		);
		
		$db->extended->autoExecute(
			Gene::tableName("discussions"),
			$discussion,
			MDB2_AUTOQUERY_INSERT
		);
		
		/* Forums Table */
		$forum = array(
			"object_id" => $newid,
			"icon_new" => 0,
			"icon_nonew" => 0,
		);
		
		$db->extended->autoExecute(
			Gene::tableName("forums"),
			$forum,
			MDB2_AUTOQUERY_INSERT
		);
		
		$newObject =& Gene_Object::get($newid);
		
		// Attempt to assign an alias
		$newObject->setAlias($newid.'-'.Gene_Object::generateAlias($title));
		
		$newObject->updateSearchIndex();
		
		return $newid;
	}
	
	/**
	 * Sets the title, description or content of the object.
	 *
	 * @var array $options Array of new content. All optional. Allowed keys:
	 *                     title - New object title
	 *                     description - New object description
	 *                     content - New object content
	 *                     revision_summary - Short summary of changes made
	 *                     revision_minor - Whether changes are minor (Boolean)
	 *
	 * @return mixed Returns true if the content has been updated,
	 *               false if nothing has updated or a PEAR_Error
	                 object if input was invalid.
	 */
	function setContent($options=array()) {
		$obj = $this->get();
		$db =& Gene::getDatabase();
		$i = array();
		
		foreach ($options as $j => $k) {
			if (in_array($j, array("title", "description", "content"))) {
				$i[$j] = $k;
			}
		}
		
		if (count($i) < 1) {
			return false;
		}
		
		// Remove new lines and check length
		if (isset($i['title'])) {
			if (strlen($i['title']) < 3) {
				return PEAR::raiseError("You must specify a title of at least 3 characters.");
			}
			
			$i['title'] = str_replace (array("\n", "\r"), '', $i['title']);
		}
		if (isset($i['description'])) {
			$i['description'] = str_replace (array("\n", "\r"), '', $i['description']);
		}
		
		// Clean Content
		if (isset($i['content'])) {
			$i['content'] = Gene_Object::cleanHtml($i['content']);
		}
		
		$i['t_modify'] = time();
		
		$db->extended->autoExecute(
			Gene::tableName("objects"),
			$i,
			MDB2_AUTOQUERY_UPDATE,
			"object_id=".$db->quote((int)$obj['object_id'])
		);
		
		/* Revisions */
		if (!isset($options['revision_summary'])) {
			$options['revision_summary'] = "";
		}
		
		if (isset($options['revision_minor'])) {
			$options['revision_minor'] = $options['revision_minor'] ? '1' : '0';
		} else {
			$options['revision_minor'] = '0';
		}
		
		$title = isset($i['title']) ? $i['title'] : $obj['title'];
		$description = isset($i['description']) ? $i['description'] : $obj['description'];
		$content = isset($i['content']) ? $i['content'] : $obj['content'];

		$user =& Gene::getUser();
		
		// Insert revision
		$revision = array(
			"revision_id" => $db->nextId(Gene::tableName("object_revisions")),
			"object_id" => intval($obj['object_id']),
			"title" => $title,
			"description" => $description,
			"content" => $content,
			"rev_summary" => $options['revision_summary'],
			"rev_minor" => $options['revision_minor'],
			"rev_time" => time(),
			"user_id" => $user->getUserId(),
		);
		
		$db->extended->autoExecute(
			Gene::tableName("object_revisions"),
			$revision,
			MDB2_AUTOQUERY_INSERT
		);
		
		$this->updateSearchIndex();
		
		return true;
	}
	
	/**
	 * Returns the object ID of the forum centre this forum belongs to.
	 *
	 * @return mixed integer forum centre ID or false if this object does not
	 *               belong to a forum centre.
	 */
	function getCentreId() {
		$p = array_reverse($this->getParents());
		if (count($p)) {
			foreach ($p as $i) {
				if ($i['type'] == "forumcentre") {
					return $i['object_id'];
				} else if ($i['type'] != "forum") {
					return false;
				}
			}
		}
		
		return false;
	}
	
	/**
	 * Returns whether this forum is standalone (no forum centre)
	 *
	 * @return boolean Whether this forum is standalone
	 */
	function isStandalone() {
		if ($this->getCentreId()) {
			return false;
		} else {
			return true;
		}
	}
	
	/**
	 * Returns objects which have been reported and number of reports
	 *
	 * @var boolean $byDiscussion group report by discussion id rather than object id.
	 * @var boolean $getInfo Whether to retrieve object information
	 */
	function getReports($byDiscussion=false, $getInfo=false) {
		$db =& Gene::getDatabase();
		$info = $this->get();
		
		if ($byDiscussion) {
			if ($getInfo) {
				$q = $db->prepare ("SELECT g.*, r.discussion_id, COUNT(r.user_id) AS reports, o.*, u.name FROM ".Gene::tableName("forum_reports")." r LEFT JOIN ".Gene::tableName("objects")." o ON (r.discussion_id=o.object_id) LEFT JOIN ".Gene::tableName("user_info")." u ON (o.owner_id=u.user_id) LEFT JOIN ".Gene::tableName("object_guests")." g ON (o.object_id=g.object_id) WHERE r.forum_id=? GROUP BY r.discussion_id ORDER BY reports DESC");
			} else {
				$q = $db->prepare ("SELECT discussion_id, COUNT(user_id) AS reports FROM ".Gene::tableName("forum_reports")." WHERE forum_id=? GROUP BY discussion_id ORDER BY reports DESC");
			}
		} else {
			if ($getInfo) {
				$q = $db->prepare ("SELECT g.*, r.object_id, COUNT(r.user_id) AS reports, o.*, u.name FROM ".Gene::tableName("forum_reports")." r LEFT JOIN ".Gene::tableName("objects")." o ON (r.object_id=o.object_id) LEFT JOIN ".Gene::tableName("user_info")." u ON (o.owner_id=u.user_id) LEFT JOIN ".Gene::tableName("object_guests")." g ON (o.object_id=g.object_id) WHERE r.forum_id=? GROUP BY r.object_id ORDER BY reports DESC");
			} else {
				$q = $db->prepare ("SELECT object_id, COUNT(user_id) AS reports FROM ".Gene::tableName("forum_reports")." WHERE forum_id=? GROUP BY object_id ORDER BY reports DESC");
			}
		}
		
		$res = $q->execute(array($info['object_id']));
		return $res->fetchAll();
	}
}
 
?>